package kubernetes

import (
	"context"
	"errors"
	"k8s-admin/global"
	"k8s-admin/utils"
	"strconv"
	"time"

	v1 "k8s.io/api/core/v1"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/intstr"
	"k8s.io/apimachinery/pkg/util/json"
)

type ServicesList struct {
	Items *v1.ServiceList
	Total int `json:"total"`
}

func (s k8sCluster) GetClusterServiceList(cid, namespace string) (*ServicesList, error) {
	cache, err := utils.GetCache(cid)
	if err != nil {
		global.TPLogger.Error("Node管理模块获取节点:", errors.New("当前集群不存在"))
		return nil, err
	} else {
		var (
			ctx    context.Context
			cancel context.CancelFunc
		)
		ctx, cancel = context.WithTimeout(context.TODO(), time.Second*5)
		defer cancel()
		list, err := cache.CoreV1().Services(namespace).List(ctx, metav1.ListOptions{})
		if err != nil {
			global.TPLogger.Error("Services模块获取失败: ", errors.New(err.Error()))
			return nil, err
		} else {
			return &ServicesList{
				Items: list,
				Total: len(list.Items),
			}, nil
		}
	}

}

func (s k8sCluster) GetClusterServiceInfo(cid, namespace, serviceName string) (*v1.Service, error) {
	cache, err := utils.GetCache(cid)
	if err != nil {
		global.TPLogger.Error("Node管理模块获取节点:", errors.New("当前集群不存在"))
		return nil, err
	} else {
		var (
			ctx    context.Context
			cancel context.CancelFunc
		)
		ctx, cancel = context.WithTimeout(context.TODO(), time.Second*5)
		defer cancel()
		get, err := cache.CoreV1().Services(namespace).Get(ctx, serviceName, metav1.GetOptions{})
		if err != nil {
			global.TPLogger.Error("Services详情信息获取失败: ", errors.New(err.Error()))
			return nil, err
		} else {
			return get, nil
		}
	}
}

func (s k8sCluster) CreateClusterService(cid, namespace, name, protocol, port, targetPort, ServiceType, nodePort string) error {
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)
	var svc_type interface{}
	svc_port, _ := strconv.Atoi(port)
	svc_targetPort, _ := strconv.Atoi(targetPort)
	switch ServiceType {
	case "ClusterIP":
		svc_type = v1.ServiceTypeClusterIP
	case "NodePort":
		svc_type = v1.ServiceTypeNodePort
	case "LoadBalancer":
		svc_type = v1.ServiceTypeLoadBalancer
	case "ExternalIP":
		svc_type = v1.ServiceTypeExternalName
	default:
		svc_type = v1.ServiceTypeClusterIP
	}
	ctx, cancel = context.WithTimeout(context.TODO(), time.Second*10)
	cache, err := utils.GetCache(cid)
	defer cancel()
	if err != nil {
		global.TPLogger.Error(err.Error())
	}

	service := &v1.Service{
		ObjectMeta: metav1.ObjectMeta{
			Name:      name,
			Namespace: namespace,
		},
		Spec: v1.ServiceSpec{
			Selector: map[string]string{},
			Ports: []v1.ServicePort{
				{
					Protocol:   v1.Protocol(protocol),
					Port:       int32(svc_port),
					TargetPort: intstr.FromInt(svc_targetPort),
				},
			},
			// Type: v1.ServiceTypeNodePort,
			Type: svc_type.(v1.ServiceType),
		},
	}
	_, err = cache.CoreV1().Services(namespace).Create(ctx, service, metav1.CreateOptions{})
	if err != nil {
		global.TPLogger.Error("创建Services失败:", err.Error())
		return errors.New("svc创建失败")
	} else {
		return nil
	}
}

func (s *k8sCluster) CreateClusterServiceYaml(cid, Namespace string, YamlData string) error {
	cache, err := utils.GetCache(cid)
	if err != nil {
		global.TPLogger.Error("Node管理模块获取节点:", errors.New("当前集群不存在"))
		return err

	} else {
		var (
			ctx    context.Context
			cancel context.CancelFunc
		)
		ctx, cancel = context.WithTimeout(context.TODO(), time.Second*5)
		defer cancel()
		// 将前端传送过来的json数据进行解析
		dest, err := utils.DecodeBase64(YamlData)
		if err != nil {
			return err
		} else {
			service := &v1.Service{}
			err = json.Unmarshal([]byte(dest), service)
			if err != nil {
				global.TPLogger.Error(err)
				return err
			}
			_, err = cache.CoreV1().Services(Namespace).Create(ctx, service, metav1.CreateOptions{})
			if err != nil {
				global.TPLogger.Error("创建Service失败:", err.Error())
				return err
			} else {
				return nil
			}
		}
	}
}

func (s *k8sCluster) DeleteK8sClusterService(cid, namespace, ServiceName string) error {
	cache, err := utils.GetCache(cid)
	if err != nil {
		global.TPLogger.Error("Node管理模块获取节点:", errors.New("当前集群不存在"))
		return err

	} else {
		var (
			ctx    context.Context
			cancel context.CancelFunc
		)
		ctx, cancel = context.WithTimeout(context.TODO(), time.Second*5)
		defer cancel()
		err = cache.CoreV1().Services(namespace).Delete(ctx, ServiceName, metav1.DeleteOptions{})
		if err != nil {
			global.TPLogger.Error("删除Service失败:", err.Error())
			return err
		} else {
			return nil
		}
	}
}

func (s *k8sCluster) UpdateClusterService(cid, Namespace, YamlData string) error {
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)
	ctx, cancel = context.WithTimeout(context.TODO(), time.Second*10)
	cache, err := utils.GetCache(cid)
	defer cancel()
	dest, err := utils.DecodeBase64(YamlData)
	if err != nil {
		return err
	} else {
		service := &v1.Service{}
		err := json.Unmarshal([]byte(dest), service)
		if err != nil {
			return err
		}
		_, err = cache.CoreV1().Services(Namespace).Update(ctx, service, metav1.UpdateOptions{})
		if err != nil {
			global.TPLogger.Error(err.Error())
			return errors.New("Service资源更新失败")
		} else {
			return nil
		}
	}
}
